using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq.Expressions;

namespace TrueCode.Core
{
	public static class EventsExtensions
	{
    public static void Raise(this EventHandler @event, object sender ) 
		{
			if(@event != null)
			  @event( sender, EventArgs.Empty );
		}

		public static void Raise<TSender, TEventArgs>(this EventHandler<TSender, TEventArgs> @event, TSender sender, TEventArgs evetntArgs) 
			where TEventArgs : EventArgs
		{
			if(@event != null)
			{
				@event(sender, evetntArgs);
			}
		}

		public static void RaiseAsync<TSender, TEventArgs>(this EventHandler<TSender, TEventArgs> @event, TSender sender, TEventArgs evetntArgs) 
			where TEventArgs : EventArgs
		{
			if(@event != null)
			{
				@event.BeginInvoke(sender, evetntArgs, @event.EndInvoke, null);
			}
		}

		public static void Raise<TSender, TArgs>(this EventHandler<TSender, EventArgs<TArgs>> @event, TSender sender, TArgs args)
		{
			if(@event != null)
			{
				@event(sender, new EventArgs<TArgs>(args));
			}
		}

		public static void RaiseAsync<TSender, TArgs>(this EventHandler<TSender, EventArgs<TArgs>> @event, TSender sender, TArgs args)
		{
			if(@event != null)
			{
				@event.BeginInvoke(sender, new EventArgs<TArgs>(args), @event.EndInvoke, null);
			}
		}


		public static void Raise<TSender>(this EventHandler<TSender, EventArgs> @event, TSender sender)
		{
			if(@event != null)
			{
				@event(sender, EventArgs.Empty);
			}
		}

		public static void RaiseAsync<TSender>(this EventHandler<TSender, EventArgs> @event, TSender sender)
		{
			if(@event != null)
			{
				@event.BeginInvoke(sender, EventArgs.Empty, @event.EndInvoke, null);
			}
		}

		public static void Raise(this PropertyChangedEventHandler @event, object sender, string propertyName)
		{
		  if( @event != null )
		    @event( sender, new PropertyChangedEventArgs( propertyName ) );
		}

    public static void Raise< T >( this PropertyChangedEventHandler @event, object sender, Expression< Func< T > > property )
    {
      if( @event != null )
        @event( sender, new PropertyChangedEventArgs( nameof.Property( property ) ) );
    }
	}
}